package com.learn.rpc.version.version6;

import com.learn.rpc.common.AdminUserServiceImpl;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 动态实现远程调用,动态实现类和方法的调用
 * @author wangxing
 * @version 2020/8/14 18:39 Administrator
 */
public class RpcServer {
    private static boolean running = true;
    public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException,
            IllegalAccessException, InvocationTargetException, InstantiationException {
        ServerSocket serverSocket = new ServerSocket(Stub.PORT);
        while(running){
            Socket socket = serverSocket.accept();
//            process(socket);
            process(socket);
            socket.close();
        }
    }

    /**
     * 动态实现远程调用,使用反射创建对象
     * @param socket
     * @throws IOException
     * @throws ClassNotFoundException
     * @throws NoSuchMethodException
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     */
    private static void process(Socket socket) throws IOException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {
        ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
        String className = objectInputStream.readUTF();
        String methodName = objectInputStream.readUTF();
        Class[] paramsType = (Class[]) objectInputStream.readObject();
        Object[] params = (Object[]) objectInputStream.readObject();

        Class clazz = getInterfaceClass(className);
        Method method = clazz.getMethod(methodName,paramsType);
        Object object = (Object)method.invoke(clazz.newInstance(), params);

        ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
        objectOutputStream.writeObject(object);
        socket.close();
        objectInputStream.close();
        objectOutputStream.close();
    }
    static final String  I_ADMIN_USER_SERVICE = "com.learn.rpc.common.IAdminUserService";
    /**
     * 通过接口名称获取接口的实现类
     * @param interfaceName 接口名称
     * @return
     */
    private static Class getInterfaceClass(String interfaceName) throws ClassNotFoundException {
        System.out.println(interfaceName);
        if(I_ADMIN_USER_SERVICE.equals(interfaceName)){
            return AdminUserServiceImpl.class;
        }
        return AdminUserServiceImpl.class;
    }
}
